#pragma once

#include <iostream>
#include <sys/epoll.h>


class Epoll
{
    const static int gnum =  256;  //设置的能监视是否就绪的最大文件描述符数量
    const static int gtimeout = 100   ; // 设置阻塞/非阻塞/定数阻塞

private:
    
    int _epfd; 
    int _timeout; 
    // int gnum ; 

public:
    Epoll(int timeout = gtimeout)
        :_timeout(gtimeout)
    {}

    void EpollCreate()
    {
        _epfd = epoll_create(gnum);
        if(_epfd < 0)
        {
            //epoll模型创建失败
            exit(5);
        }

    }

    bool AddSockToEpoll(int sock , uint32_t events)
    {
        epoll_event  ev ;
        ev.events = events ; 
        ev.data.fd = sock ; 
        int n = epoll_ctl(_epfd, EPOLL_CTL_ADD, sock, &ev);
        return n == 0 ; 
    }

    int WaitEpoll(epoll_event revs[], int num)
    {
        return epoll_wait(_epfd, revs, num, _timeout);
    }

    bool DelFromEpoll(int sock)
    {
        int n = epoll_ctl(_epfd, EPOLL_CTL_DEL, sock, nullptr);
        return n==0 ; //n==0表成功
    }

    bool CtrlEpoll(int sock, uint32_t events)
    {
        events |= EPOLLET ; 
        //边缘触发
        //仔细想想边缘或者水平触发模式的设置是于文件描述符而言的，是否可以一部分水平触发一部分边缘触发呢
        epoll_event ev ; 
        ev.data.fd = sock ;
        ev.events = events ;
        int n = epoll_ctl(_epfd, EPOLL_CTL_DEL, sock, &ev);

        return n == 0 ;
    }

    ~Epoll()
    {

    }
};



